
#include <fcntl.h>
#include <memory.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <unistd.h>

unsigned long* get_addr()
{
    void* pmem;
    // const char* dev_file = "/dev/dev_alt_mem_2";
    // const char* dev_file = "/dev/zero";
    const char* dev_file = "/dev/mem";
    int fd;
    int map_size = 1024;
    int page_size = 4096;

    /*
	 * open alt_mem driver, map BAR memory.
	 */
    if ((fd = open(dev_file, O_RDWR)) < 0) {
        fprintf(stdout, "file cannot open\n");
        exit(1);
    }

    if (!(pmem = malloc(map_size + page_size))) {
        printf("mallo error\n");
        exit(2);
    }

    printf("%p\n", pmem);

    // pmem = mmap(pmem, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    // pmem = mmap(pmem, map_size, PROT_READ, MAP_SHARED, fd, 0);
    pmem = mmap(pmem, map_size, PROT_READ, MAP_SHARED, fd, 0);

    // pmem = (unsigned char*)(((int)pmem & ~0xfff) + 0x2ede);
    return pmem;
}

unsigned long ld_insn(unsigned long* addr) __attribute__((optimize("O2")));
unsigned long ld_insn(unsigned long* addr)
{
    unsigned long res;
    asm("ldr %[src], [%[addr]]"
        : [ src ] "=r"(res)
        : [ addr ] "r"(addr));
    return res;
}

int main()
{
    unsigned long* ptr;
    unsigned long* un_align_ptr;
    printf("pointer size; %d, long size: %d\n", sizeof(void*), sizeof(unsigned long));

    ptr = get_addr();
    un_align_ptr = (unsigned long*)(((unsigned long)ptr) + 0x2);

    unsigned long val = -1;
    printf("%p, un_align_ptr: %p: %lx\n", ptr, un_align_ptr, val);
    
    val = ld_insn(un_align_ptr);

    printf("%p, un_align_ptr: %p: %lx\n", ptr, un_align_ptr, val);
    return 0;
}
